package xq.pug.common.jwt;

import cn.hutool.core.codec.Base64;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import xq.pug.common.po.User;

import javax.crypto.SecretKey;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @program: xq_pug_alibabacloud_parent
 * @description: token的生成 解析 校验
 * @author: Mr.Ren
 * @create: 2023-05-08 22:52
 **/
public class JwtUtils {
    /**
     * Authorization认证开头是"bearer "
     */
    private static final String BEARER = "Bearer ";
    private static final String BASIC = "Basic ";

    private static final String secret = "zxcvbnmqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq";

    private static final Long expirationTimeInSecond = 1209600L;

    /**
     * 获取默认过期时间
     *
     * @return
     */
    public static Date getExpirationTime() {
        return new Date(System.currentTimeMillis() + expirationTimeInSecond * 1000);
    }

    /**
     * 获取token
     *
     * @param claims
     * @return
     */
    public static String getToken(Map<String, Object> claims) {
        Date createdTime = new Date();
        //获取token过期时间
        Date expirationTime = getExpirationTime();

        byte[] keyBytes = secret.getBytes();

        SecretKey key = Keys.hmacShaKeyFor(keyBytes);

        return Jwts.builder()
                .setClaims(claims)
                .setIssuedAt(createdTime)
                .setExpiration(expirationTime)
                //可任意选择算法
                .signWith(key, SignatureAlgorithm.HS256)
                .compact();
    }

    /**
     * @param authorization
     * @return
     */
    public static String getToken(String authorization) {
        Map<String, Object> map = new HashMap<>();
        authorization = authorization.substring(BASIC.length());
        String accountDecode = Base64.decodeStr(authorization);
        String[] split = accountDecode.split(":");
        map.put("client_id", split[0]);
        map.put("client_secret", split[1]);
        return getToken(map);
    }

    public static String getToken(User user) {
        Map<String, Object> map = new HashMap<>();

        map.put("userId", user.getUserId());
        map.put("userName", user.getUserName());
        map.put("role", user.getRole());

        return getToken(map);
    }


    public static String getTokenByUsername(String username) {
        Map<String, Object> map = new HashMap<>();

        map.put("username", username);

        return getToken(map);
    }

    /**
     * 判断token是否合法
     *
     * @param token
     * @return
     */
    public static Boolean validateToken(String token) {
        try {
            return !isTokenExpired(token);
        } catch (Exception e) {
            return false;
        }


    }

    /**
     * token是否过期
     *
     * @param token
     * @return
     */
    public static Boolean isTokenExpired(String token) {
        //过期时间
        Date expiration = getExpirationDateFromToken(token);
        return expiration.before(new Date());
    }

    /**
     * 从token中获取过期时间
     *
     * @param token
     * @return
     */
    public static Date getExpirationDateFromToken(String token) {
        return getClaimsFromToken(token).getExpiration();
    }

    /**
     * 从token中获取claims
     *
     * @param token
     * @return
     */
    public static Claims getClaimsFromToken(String token) {
        return Jwts.parserBuilder()
                .setSigningKey(secret.getBytes())
                .build()
                .parseClaimsJws(token)
                .getBody();
    }

    /**
     * 从token中获取claims
     *
     * @param jwtToken 携带前缀 Bearer的token
     * @return
     */
    public static Jws<Claims> getJwt(String jwtToken) {
        if (jwtToken.startsWith(BEARER)) {
            jwtToken = jwtToken.substring(BEARER.length());
        }
        return Jwts.parserBuilder()
                .setSigningKey(secret.getBytes())
                .build().parseClaimsJws(jwtToken);
    }

}
